home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / treedir.c < prev    next >
Text File  |  1985-06-03  |  5KB  |  237 lines

  1. /*
  2.     TREEDIR  --  Tree directory for MSDOS V2.xx.
  3.  
  4.             usage:    TREEDIR  [directory]
  5.  
  6.     If the directory is omitted, the tree starts with the root
  7.     directory.    Use TREEDIR .  to start from the current directory.
  8.  
  9.  
  10.     This program combines TREE and DIR to produce a directory
  11.     of all files in each directory along with date, time and
  12.     file size.
  13.  
  14.     Totals are given for each directory, which includes the
  15.     totals of any subdirectories.
  16.  
  17.     This program was primarily written to display the actual
  18.     space used on the hard disk for each directory, and the
  19.     amount of space needed to copy to a diskette.
  20.     This is due to the allocation cluster of MSDOS: files on
  21.     diskette are allocated in increments of 1024 bytes while
  22.     files on the hard disk (10 MB) are in 4096 byte chunks.
  23.  
  24.     The program as written requires Lattice c, version 2.1 or
  25.     higher.  No attempt was made to keep it portable, since
  26.     the dos interface is non-portable by definition.  The Lattice
  27.     conio.h is used instead of stdio.h, resulting in direct console
  28.     i/o and a smaller com file.
  29.  
  30.     The program also requires DOS 2.0 or higher, since it doesn't
  31.     make any sense otherwise.
  32.  
  33.     Future versions will probably include sorts and hidden files
  34.     and options like SD.
  35.  
  36.  
  37.                     Alan Losoff
  38.                     Milwaukee, Wisconsin
  39.  
  40.     revisions:
  41.         07-05-84    test for ^C hit (needed when bypassing standard i/o)
  42. */
  43.  
  44. #include <conio.h>        /* Lattice direct console I/O */
  45.  
  46. #include <stamp.h>        /* time/date file from my cc.bat */
  47. /* static char *__stamp[] = {"dd/dd/dd", "tt/tt/tt"};    */
  48.  
  49. /* BDOS CALLS */
  50. #define GETFAT 0x3600
  51. #define SETDTA 0x1A00
  52. #define FFIRST 0x4E00
  53. #define FNEXT  0x4F00
  54.  
  55. #define SUBDIR 0x0010        /* attribute for sub directory */
  56.  
  57. #define CTRL_C    3
  58.  
  59. struct XREG            /* for lattice bdos call */
  60. {
  61.     short ax,bx,cx,dx,si,di;
  62. };
  63.  
  64. struct    DIRS            /* dos directory entry */
  65. {
  66.     char    for_dos[21];
  67.     char    attr;
  68.     struct
  69.     {
  70.         unsigned hour : 5;
  71.         unsigned minute : 6;
  72.         unsigned twosec : 5;
  73.     }    time;
  74.     struct
  75.     {
  76.         unsigned year : 7;
  77.         unsigned month : 4;
  78.         unsigned day : 5;
  79.     }    date;
  80.     long    size;
  81.     char    name[13];
  82.     char    fill[85];
  83. };
  84.  
  85. struct    counts
  86. {
  87.     int    files;
  88.     int    blocks;
  89.     int    kbytes;
  90.     long    bytes;
  91. };
  92.  
  93.  
  94. int    _stack    = 10000;    /* set stack size (lattice specific) */
  95.  
  96. static     int     blocksize = 0; /* cluster size for drive specified */
  97.  
  98. main(argc, argv)
  99. int    argc;
  100. char    *argv[];
  101.  
  102. {
  103.     char    *path;
  104.  
  105.     path        = argc > 1 ? argv[1] : "";
  106.     blocksize   = cluster(path);
  107.  
  108.     printf("\nTREEDIR   Tree Directory      version 1.01%s\n\n", __stamp[0]);
  109.     printf(      "File                                 Date     Time       Size Actual Kbytes\n");
  110.  
  111.     pdir (path, 0);
  112.     exit();
  113. }
  114.  
  115. pdir (path, cp)             /* print & total for given path */
  116. char    *path;
  117. struct    counts    *cp;
  118. {
  119.     static    margin = -2;
  120.  
  121.     char    *indent();
  122.     char    newpath[129];
  123.  
  124.     struct    DIRS buf;
  125.     struct    counts    c;
  126.  
  127.     int    r, n, k;
  128.  
  129.     margin += 2;
  130.     c.bytes = c.files = c.blocks = c.kbytes = 0;
  131.  
  132.  
  133.     for (r = first(path, &buf); !r; r = next(path, &buf))
  134.     {
  135.         kbhit();        /* checks for ^C */
  136.  
  137.         if (*buf.name == '.')
  138.             continue;
  139.  
  140.         printf("%-36s", indent(margin, buf.name));
  141.         if (buf.attr & SUBDIR)
  142.         {
  143.             printf("\n");
  144.             sprintf(newpath, "%s\\%s", path, buf.name);
  145.             pdir(newpath, &c);
  146.         }
  147.         else
  148.         {
  149.             n = ((buf.size + blocksize - 1) / blocksize)
  150.               * (blocksize / 1024);
  151.             k = (buf.size + 1023) / 1024;
  152.             printf("%2d/%02d/%02d  %2d:%02d %9ld %5dK %5dk\n",
  153.                 buf.date.month, buf.date.day, buf.date.year+80,
  154.                 buf.time.hour, buf.time.minute,
  155.                 buf.size, n, k);
  156.             c.files++;
  157.             c.blocks += n;
  158.             c.kbytes += k;
  159.             c.bytes  += buf.size;
  160.         }
  161.     }
  162.     margin -= 2;
  163.     printf("%41s %4d files %9ld %5dK %5dk **\n\n",
  164.            "", c.files, c.bytes, c.blocks, c.kbytes);
  165.     if (cp)
  166.     {
  167.         cp->blocks += c.blocks;
  168.         cp->kbytes += c.kbytes;
  169.         cp->files  += c.files;
  170.         cp->bytes  += c.bytes;
  171.     }
  172.     return;
  173. }
  174.  
  175. char *
  176. indent (margin, name)            /* indent name to margin */
  177. int    margin;
  178. char    *name;
  179. {
  180.     int    n;
  181.     static    char    work[129];
  182.  
  183.     for (n = 0; n< margin; n++)
  184.         work[n] = ' ';
  185.     strcpy(work + margin, name);
  186.     return (work);
  187. }
  188.  
  189. cluster(dir)                /* return cluster size of disk */
  190. char    *dir;
  191. {
  192.     struct    XREG inregs, outregs;
  193.  
  194.     inregs.dx = dir[1] == ':' ? dir[0] & 0x1F : 0;
  195.     inregs.ax = GETFAT;
  196.     intdos(&inregs, &outregs);
  197.     return (outregs.ax * outregs.cx);
  198. }
  199.  
  200. first (dir, buf)            /* find first directory entry */
  201. char    *dir, *buf;
  202. {
  203.     struct    XREG inregs, outregs;
  204.     char    arg[129];
  205.  
  206.     inregs.ax = SETDTA;
  207.     inregs.dx = (int) buf;
  208.     intdos(&inregs, &outregs);
  209.  
  210.     sprintf(arg, "%s\\????????.???", dir);
  211.     inregs.ax = FFIRST;
  212.     inregs.cx = SUBDIR;
  213.     inregs.dx = (int) (&arg);
  214.     intdos(&inregs, &outregs);
  215.     return (outregs.ax);
  216. }
  217.  
  218. next (dir, buf)             /* find next directory entry */
  219. char    *dir, *buf;
  220. {
  221.     struct    XREG inregs, outregs;
  222.     char    arg[129];
  223.  
  224.     inregs.ax = SETDTA;
  225.     inregs.dx = (int) buf;
  226.     intdos(&inregs, &outregs);
  227.  
  228.     sprintf(arg, "%s\\*.*", dir);
  229.     inregs.ax = FNEXT;
  230.     inregs.cx = SUBDIR;
  231.     inregs.dx = (int) (&arg);
  232.     intdos(&inregs, &outregs);
  233.     return (outregs.ax);
  234. }
  235. );
  236. }
  237.